# -*- coding: utf-8 -*-
"""
特征转换
"""
from __future__ import print_function, unicode_literals


class BaseFeatureCover(object):
    """
    计算feature转换的基类
    """
    def __init__(self, len):
        self.len = len

    def _calc_one_word_base(self, line, i, pos_related=0):
        """
        针对单个词计算其所有相关的特征
        :param word:
        :return:
        """
        word = line[0][i]
        postag = line[1][i]

        features = [
            'bias',
            'postag=' + postag,

            # 整词以及后缀
            'word.upper=' + word.upper(),
            'word[-1]=' + word[-1],  # 最后一个字
            'word[0]=' + word[0],  # 第一个字
            'word[:-1]=' + word[:-1],  # 前缀
            'word[1:]=' + word[1:],  # 后缀
            'word[-2:]=' + word[-2:],
            'word[-3:]=' + word[-3:],

            'pos[0]=' + postag[0],

            # 是否含有数字
            # 'word.isdigit=%s' % self.feature_calc.is_digit(word),

            # 词库中
            # 'word.ispartproduct=%s' % self.feature_calc.is_part_product(word_flags, i, key=key),
        ]
        return features

    def to_feature(self, line):
        """
        根据配置的长度计算属性
        :param line:　words, postags, ....
        :return:
        """
        return [self._to_feature_i(line, i) for i in range(len(line[0]))]

    def _to_feature_i(self, line, i):
        """
        进行实际的特征计算
        :param line:
        :param i:
        :return:
        """
        features = self._calc_one_word_base(line, i)
        line_len = len(line[0])

        # 计算之前的项的特征
        if i == 0:
            features.append('BOS')
        else:
            pos_related = 1
            curr_pos = i - 1

            while pos_related < self.len + 1:
                if curr_pos >= 0:
                     features.extend(
                        ['-{}:'.format(pos_related) + f for f in
                         self._calc_one_word_base(line, curr_pos, -pos_related)])
                     pos_related += 1
                     curr_pos -= 1
                else:
                    break

        # 计算当前项之后的项的特征
        if i == line_len - 1:
            features.append('EOS')
        else:
            pos_related = 1
            curr_pos = i + 1

            while pos_related < self.len + 1:
                if curr_pos < line_len:
                    features.extend(
                        ['+{}:'.format(pos_related) + f for f in
                         self._calc_one_word_base(line, curr_pos, pos_related)])
                    pos_related += 1
                    curr_pos += 1
                else:
                    break

        return features


if __name__ == '__main__':
    line = [
        ['你', '是', '一个', '贱人'],
        ['nr', 'v', 'm', 'n']
    ]
    for i in BaseFeatureCover(3).to_feature(line):
        print(i)